package goalgorithm

import (
	"container/list"
	"fmt"
	"sync"
	"time"
)

/*
	时间表，适用于按时间插入的表格
	时间链表,每个链表都有一个长达1小时的缓冲区
	由于可能索引可能在同一秒，所以搜索时，需要两个参数，时间，标识
	由于开始时所有超过1小时的都放到1小时的里面了，所以到了1小时那个页时，需要对页进行重新排序
	时间只是用来排序，而id号才是唯一编号
*/

type TimeTable struct {
	sync.Mutex
	Items map[int64]*list.List   //保存所有内容  []*TimeTableNode
	V加速   map[int]*TimeTableNode //根据id加速访问
	V时间链表 list.List
}
type TimeTableNode struct {
	Item  interface{}
	Index time.Time
	id    int //这个是内容id
}

func (this *TimeTable) F初始化() {
	this.V加速 = make(map[int]*TimeTableNode)
	this.Items = make(map[int64]*list.List)
	//this.V时间链表= make(map[int64]*list.List)
}

func (this *TimeTable) ms(t time.Time) int64 {
	return t.UnixNano() / int64(time.Millisecond*10)
}
func (this *TimeTable) F获取最早时间() interface{} {
	this.Lock()
	defer this.Unlock()
	start := this.V时间链表.Front()
	if start == nil {
		return nil
	}
	n := start.Value.(int64) //获取第一个时间
	lists, _ := this.Items[n]
	v := lists.Front()
	if v == nil {
		return nil
	}
	return v.Value.(*TimeTableNode).Item
}

func (this *TimeTable) _Insert(row *TimeTableNode) {
	Index := this.ms(row.Index)
	defer func() {

		ns, ok := this.Items[Index]
		if ok == false {
			panic("")
		}
		n := ns.Front()
		for {
			if n.Value.(*TimeTableNode).id == row.id {
				if n.Value.(*TimeTableNode).Index != row.Index {
					panic("")
				}
				break
			}
			if n.Next() == nil {
				fmt.Println("DEBUG 没有后续", row.id, ns.Len())
			}
			n = n.Next()
		}
		tnode := this.V时间链表.Front()
		for {
			v := tnode.Value.(int64)
			if Index == v {
				break
			}
			tnode = tnode.Next()
		}
	}()
	if nodes, ok := this.Items[Index]; ok == false {
		nodes = &list.List{}
		nodes.Init()
		nodes.PushFront(row)
		this.Items[Index] = nodes

		tnode := this.V时间链表.Front()
		if tnode == nil {
			this.V时间链表.PushFront(Index)
		} else {
			for {
				v := tnode.Value.(int64)
				if Index < v {
					this.V时间链表.InsertBefore(Index, tnode)
					break
				}
				if tnode.Next() == nil {
					this.V时间链表.InsertAfter(Index, tnode)
					break
				} else {
					tnode = tnode.Next()
				}
			}
		}
	} else {
		node := nodes.Front()
		for {
			v := node.Value.(*TimeTableNode)
			if row.Index.Sub(v.Index).Seconds() < 0 {
				nodes.InsertBefore(row, node)
				break
			}
			if node.Next() == nil {
				nodes.InsertAfter(row, node)
				break
			} else {
				node = node.Next()
			}
		}
	}
	if _, ok := this.V加速[row.id]; ok == false {
		this.V加速[row.id] = row
	} else {
		panic("")
	}
}
func (this *TimeTable) Test() {
	this.F初始化()
	for i := 0; i < 1000; i++ {
		t := time.Now()
		_ = this.Insert(t, int(i), i)
		ret := this.Delete(int(i))
		if ret == nil {
			panic("")
		}
	}
}

/*
功能: 在主链表中插入一个数据
*/
func (this *TimeTable) Insert(时间 time.Time, id int, item interface{}) *TimeTableNode {
	this.Lock()
	defer this.Unlock()

	row := &TimeTableNode{Index: 时间, id: id, Item: item}
	this._Insert(row)
	return row
}
func (this *TimeTable) Delete(id int) interface{} {
	this.Lock()
	defer this.Unlock()
	var ret interface{}
	row, 加速 := this.V加速[id]
	if 加速 == false {
		return nil
	}
	delete(this.V加速, id)
	Index := this.ms(row.Index)
	nodes, 已有 := this.Items[Index]

	if 已有 == false {
		panic("")
	}
	node := nodes.Front()
	for {
		v := node.Value.(*TimeTableNode)
		if v.id == id {
			nodes.Remove(node)
			ret = v.Item
			break
		}
		if node.Next() == nil {
			panic("")
		} else {
			node = node.Next()
		}
	}
	if nodes.Len() == 0 { //如果没有数据了
		delete(this.Items, Index) //删除这个链表
		tnode := this.V时间链表.Front()
		for {
			v := tnode.Value.(int64)
			if Index == v {
				this.V时间链表.Remove(tnode)
				break
			}
			if tnode.Next() == nil {
				panic("")
			} else {
				tnode = tnode.Next()
			}
		}
	}
	return ret
}
